#include "HIDPS2conv.h"
#include "ps2_client_kb.h"

#ifndef _HID_PS2_conv_KB_H
#define _HID_PS2_conv_KB_H

#define KEY_SET_MAX 0x8F

// 美式键盘映射表
// (HID键盘到PS/2键盘的编码映射)
//  下标：usb键盘码
//  值：对应的PS/2扫描码的序列号
//      0：不支持
const uint8_t USBtoPS2_US_Index[] = {
    0,   // 0x00 N/A(no event)
    0,   // 0x01 N/A(error Roll over)
    0,   // 0x02 N/A(post fail)
    0,   // 0x03 N/A(undefined)
    1,   // 0x04 A
    2,   // 0x05 B
    3,   // 0x06 C
    4,   // 0x07 D
    5,   // 0x08 E
    6,   // 0x09 F
    7,   // 0x0A G
    8,   // 0x0B H
    9,   // 0x0C I
    10,  // 0x0D J
    11,  // 0x0E K
    12,  // 0x0F L
    13,  // 0x10 M
    14,  // 0x11 N
    15,  // 0x12 O
    16,  // 0x13 P
    17,  // 0x14 Q
    18,  // 0x15 R
    19,  // 0x16 S
    20,  // 0x17 T
    21,  // 0x18 U
    22,  // 0x19 V
    23,  // 0x1A W
    24,  // 0x1B X
    25,  // 0x1C Y
    26,  // 0x1D Z
    28,  // 0x1E 1
    29,  // 0x1F 2
    30,  // 0x20 3
    31,  // 0x21 4
    32,  // 0x22 5
    33,  // 0x23 6
    34,  // 0x24 7
    35,  // 0x25 8
    36,  // 0x26 9
    27,  // 0x27 0
    54,  // 0x28 return
    55,  // 0x29 Esc
    41,  // 0x2A backspace
    43,  // 0x2B tab
    42,  // 0x2C space
    38,  // 0x2D - _
    39,  // 0x2E = +
    71,  // 0x2F [ {
    99,  // 0x30 ] }
    40,  // 0x31 \ |
    0,   // 0x32
    100, // 0x33 ; :
    101, // 0x34 ' "
    37,  // 0x35 ` ~
    102, // 0x36 , <
    103, // 0x37 . >
    104, // 0x38 / ?
    44,  // 0x39 caps lock
    56,  // 0x3A F1
    57,  // 0x3B F2
    58,  // 0x3C F3
    59,  // 0x3D F4
    60,  // 0x3E F5
    61,  // 0x3F F6
    62,  // 0x40 F7
    63,  // 0x41 F8
    64,  // 0x42 F9
    65,  // 0x43 F10
    66,  // 0x44 F11
    67,  // 0x45 F12
    68,  // 0x46 print screen
    69,  // 0x47 scroll lock
    70,  // 0x48 pause
    72,  // 0x49 insert
    73,  // 0x4A home
    74,  // 0x4B page up
    75,  // 0x4C del
    76,  // 0x4D end
    77,  // 0x4E page down
    81,  // 0x4F right
    79,  // 0x50 left
    80,  // 0x51 down
    78,  // 0x52 up
    82,  // 0x53 num lock
    83,  // 0x54 num /
    84,  // 0x55 num *
    85,  // 0x56 num -
    86,  // 0x57 num +
    87,  // 0x58 num enter
    90,  // 0x59 num 1
    91,  // 0x5A num 2
    92,  // 0x5B num 3
    93,  // 0x5C num 4
    94,  // 0x5D num 5
    95,  // 0x5E num 6
    96,  // 0x5F num 7
    97,  // 0x60 num 8
    98,  // 0x61 num 9
    89,  // 0x62 num 0
    88,  // 0x63 num . del
    00,  // 0x64
    53,  // 0x65 application
    110, // 0x66 power
    0,   // 0x67
    0,   // 0x68 F13
    0,   // 0x69 F14
    0,   // 0x6A F15
    0,   // 0x6B F16
    0,   // 0x6C F17
    0,   // 0x6D F18
    0,   // 0x6E F19
    0,   // 0x6F F20
    0,   // 0x70 F21
    0,   // 0x71 F22
    0,   // 0x72 F23
    0,   // 0x73 F24
    0,   // 0x74 execute
    0,   // 0x75 help
    0,   // 0x76 Menu
    0,   // 0x77 select
    0,   // 0x78 stop
    0,   // 0x79 again
    0,   // 0x7A undo
    0,   // 0x7B cut
    0,   // 0x7C copy
    0,   // 0x7D paste
    0,   // 0x7E find
    0,   // 0x7F mute
    0,   // 0x80 volume up
    0,   // 0x81 volume down
    0,   // 0x82
    0,   // 0x83
    0,   // 0x84
    0,   // 0x85
    0,   // 0x86
    0,   // 0x87 JPN \ -
    0,   // 0x88 JPN 输入方式变换
    0,   // 0x89 JPN 羊
    0,   // 0x8A JPN 变换
    0,   // 0x8B JPN 无变换
    0,   // 0x8C
    0,   // 0x8D
    0,   // 0x8E
    0,   // 0x8F
};

// 日式键盘映射表
// (HID键盘到PS/2键盘的编码映射)
//  下标：usb键盘码
//  值：对应的PS/2扫描码的序列号
//      0：不支持
const uint8_t USBtoPS2_JIS_Index[] = {
    0,   // 0x00 N/A(no event)
    0,   // 0x01 N/A(error Roll over)
    0,   // 0x02 N/A(post fail)
    0,   // 0x03 N/A(undefined)
    1,   // 0x04 A
    2,   // 0x05 B
    3,   // 0x06 C
    4,   // 0x07 D
    5,   // 0x08 E
    6,   // 0x09 F
    7,   // 0x0A G
    8,   // 0x0B H
    9,   // 0x0C I
    10,  // 0x0D J
    11,  // 0x0E K
    12,  // 0x0F L
    13,  // 0x10 M
    14,  // 0x11 N
    15,  // 0x12 O
    16,  // 0x13 P
    17,  // 0x14 Q
    18,  // 0x15 R
    19,  // 0x16 S
    20,  // 0x17 T
    21,  // 0x18 U
    22,  // 0x19 V
    23,  // 0x1A W
    24,  // 0x1B X
    25,  // 0x1C Y
    26,  // 0x1D Z
    28,  // 0x1E 1
    29,  // 0x1F 2
    30,  // 0x20 3
    31,  // 0x21 4
    32,  // 0x22 5
    33,  // 0x23 6
    34,  // 0x24 7
    35,  // 0x25 8
    36,  // 0x26 9
    27,  // 0x27 0
    54,  // 0x28 return
    55,  // 0x29 Esc
    41,  // 0x2A backspace
    43,  // 0x2B tab
    42,  // 0x2C space
    38,  // 0x2D - =
    39,  // 0x2E ^ ~
    71,  // 0x2F @ ·
    99,  // 0x30 [ {
    0,   // 0x31
    105, // 0x32 ] }
    100, // 0x33 ; +
    101, // 0x34 : *
    37,  // 0x35 半角/全角|汉字
    102, // 0x36 , <
    103, // 0x37 . >
    104, // 0x38 / ?
    44,  // 0x39 caps lock
    56,  // 0x3A F1
    57,  // 0x3B F2
    58,  // 0x3C F3
    59,  // 0x3D F4
    60,  // 0x3E F5
    61,  // 0x3F F6
    62,  // 0x40 F7
    63,  // 0x41 F8
    64,  // 0x42 F9
    65,  // 0x43 F10
    66,  // 0x44 F11
    67,  // 0x45 F12
    68,  // 0x46 print screen
    69,  // 0x47 scroll lock
    70,  // 0x48 pause
    72,  // 0x49 insert
    73,  // 0x4A home
    74,  // 0x4B page up
    75,  // 0x4C del
    76,  // 0x4D end
    77,  // 0x4E page down
    81,  // 0x4F right
    79,  // 0x50 left
    80,  // 0x51 down
    78,  // 0x52 up
    82,  // 0x53 num lock
    83,  // 0x54 num /
    84,  // 0x55 num *
    85,  // 0x56 num -
    86,  // 0x57 num +
    87,  // 0x58 num enter
    90,  // 0x59 num 1
    91,  // 0x5A num 2
    92,  // 0x5B num 3
    93,  // 0x5C num 4
    94,  // 0x5D num 5
    95,  // 0x5E num 6
    96,  // 0x5F num 7
    97,  // 0x60 num 8
    98,  // 0x61 num 9
    89,  // 0x62 num 0
    88,  // 0x63 num . del
    00,  // 0x64
    53,  // 0x65 application
    120, // 0x66 power
    0,   // 0x67
    0,   // 0x68 F13
    0,   // 0x69 F14
    0,   // 0x6A F15
    0,   // 0x6B F16
    0,   // 0x6C F17
    0,   // 0x6D F18
    0,   // 0x6E F19
    0,   // 0x6F F20
    0,   // 0x70 F21
    0,   // 0x71 F22
    0,   // 0x72 F23
    0,   // 0x73 F24
    0,   // 0x74 execute
    0,   // 0x75 help
    0,   // 0x76 Menu
    0,   // 0x77 select
    0,   // 0x78 stop
    0,   // 0x79 again
    0,   // 0x7A undo
    0,   // 0x7B cut
    0,   // 0x7C copy
    0,   // 0x7D paste
    0,   // 0x7E find
    0,   // 0x7F mute
    0,   // 0x80 volume up
    0,   // 0x81 volume down
    0,   // 0x82
    0,   // 0x83
    0,   // 0x84
    0,   // 0x85
    0,   // 0x86
    106, // 0x87 JPN \ -
    107, // 0x88 JPN 输入方式变换
    108, // 0x89 JPN 羊 |
    109, // 0x8A JPN 变换
    110, // 0x8B JPN 无变换
    0,   // 0x8C
    0,   // 0x8D
    0,   // 0x8E
    0,   // 0x8F
};

// 特殊按键键盘映射表
//  下标：usb键盘码
//  值：对应的PS/2扫描码
//      0x00：不支持
const uint8_t PS2_SET2_MAKE_SP[] = {
    46, // 0 0x01 L ctrl
    45, // 1 0x02 L shift
    48, // 2 0x04 L Alt
    47, // 3 0x08 L WIN
    50, // 4 0x10 R ctrl
    49, // 5 0x20 R shift
    52, // 6 0x40 R Alt
    51  // 7 0x80 R WIN
};

class HIDPS2conv_KB : public HIDPS2conv, public PS2_Client_KB_Callbacks {
private:
    static PS2_Client_KB *_PS2Client;

    void onRecvDataHID(int num, uint8_t *dataBuf, int nLen);

    uint8_t KeyStatus[120];    // （PS2编码表）记录每个按键当前状态 0：释放， 1按下
    uint8_t KeyStatusTmp[120]; // （PS2编码表）所有按键的新状态 0：释放， 1按下

public:
    void init(PS2_Client_KB *pPS2Client);
    static void ble_onRecvDataHID(BleServerConnector *pConnector, uint8_t *dataBuf, int nLen);
    static void usb_onRecvDataHID(USBClientConnector *pConnector, uint8_t *dataBuf, int nLen);

    uint8_t usb_to_ps2_index(int keyboard_mode, uint8_t code);
    uint8_t usb_to_ps2_index_sp(uint8_t code);

    bool addHidDevice(BleServerConnector *pConnector);
    bool addHidDevice(USBClientConnector *pConnector);

    // 回调函数
    void ps2kb_setLED(uint8_t param);
};

extern HIDPS2conv_KB _HIDPS2conv_KB;

#endif
